/// 问号？的其他用法
/// ```rust
/// .and_then(|s| s.parse::<i32>())
///   .map_err(|e| e.into())
/// ```
/// 
/// 这段代码的作用是：
/// 
/// 1. `and_then` 方法的作用是：如果 `Result` 类型是 `Ok`，则返回 `Ok` 值，否则，对 `Err` 值进行操作，返回新的 `Result` 类型。
/// 
/// 2. `map_err` 方法的作用是：对 `Err` 值进行操作，返回新的 `Err` 类型。
/// 
/// 3. `into()` 方法的作用是：将 `Err` 类型转换为 `Box<dyn Error>` 类型。
/// 
/// 4. `Box<dyn Error>` 是一个 trait 对象，可以作为 `Err` 类型。
/// 
/// 5. 这段代码的作用是：如果 `parse::<i32>()` 失败，则返回新的 `Err` 类型，否则，返回 `Ok` 值。
/// 

/// ? 的其他用法  是可以把上面的常用功能简化，把错误类型自动向上转换为 `Box<dyn Error>` 类型。

use std::error;
use std::fmt;

// Change the alias to use `Box<dyn error::Error>`.
type Result<T> = std::result::Result<T, Box<dyn error::Error>>;

#[derive(Debug)]
struct EmptyVec;

impl fmt::Display for EmptyVec {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "invalid first item to double")
    }
}

impl error::Error for EmptyVec {}

// The same structure as before but rather than chain all `Results`
// and `Options` along, we `?` to get the inner value out immediately.
/// 这样的写法，就是不能像前面那样连起来写了，但是也更清析了，好理解
fn double_first(vec: Vec<&str>) -> Result<i32> {
    let first = vec.first().ok_or(EmptyVec)?;
    let parsed = first.parse::<i32>()?;
    Ok(2 * parsed)
}

fn print(result: Result<i32>) {
    match result {
        Ok(n)  => println!("The first doubled is {}", n),
        Err(e) => println!("Error: {}", e),
    }
}

fn main() {
    let numbers = vec!["42", "93", "18"];
    let empty = vec![];
    let strings = vec!["tofu", "93", "18"];

    print(double_first(numbers));
    print(double_first(empty));
    print(double_first(strings));
}